package cn.tedu.micro.demo.rabbit.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 *这个配置类专门声明业务所需组件用的
 *声明一个路由交换机 Direct  direct_demo_ex
 *声明一个普通队列 Queue demo_queue
 *确定绑定关系 demo_rk做路由key值绑定
 */
@Configuration
@Slf4j
public class DeclareConfiguration {
    //死信处理延迟的名称
    private static final String DELAY_EX="delay_ex";
    private static final String DELAY_Q="delay_q";
    private static final String DLX_EX="dlx_ex";
    private static final String DLX_Q="dlx_q";
    private static final String DLX_RK="dlx_rk";
    //声明2个交换机 延迟交换机 fanout 死信交换机direct
    @Bean
    public Exchange delayExchange(){
        return new TopicExchange(DELAY_EX);
    }
    @Bean
    public Exchange dlxExchange(){
        return new DirectExchange(DLX_EX);
    }
    //声明延迟队列 绑定死信交换机和死信路由
    @Bean
    public Queue delayQueue(){
        return QueueBuilder.nonDurable(DELAY_Q)
                .deadLetterExchange(DLX_EX)
                .deadLetterRoutingKey(DLX_RK).build();
    }
    //声明死信队列
    @Bean
    public Queue dlxQueue(){
        return new Queue(DLX_Q, false);
    }
    //延迟队列和延迟交换机
    @Bean
    public Binding delayBinding(){
        return BindingBuilder
                .bind(delayQueue())
                .to(delayExchange())
                .with("").noargs();
    }
    @Bean
    public Binding dlxBinding(){
        return BindingBuilder
                .bind(dlxQueue())
                .to(dlxExchange())
                .with(DLX_RK).noargs();
    }

    //channel.exchangeDeclare(名字,类型)
    /**
     * 交换机类型提取了抽象Exchange 根据不同类型封装了
     * DirectExchange
     * FanoutExchange
     * HeadersExchange
     * TopicExchange
     */
    @Bean
    public Exchange directDemoEx(){
        log.info("构造demo的交换机");
        //1.方案 直接new 通过构造参数传递底层案例的参数值
        //return new DirectExchange("direct_demo_ex");
        //2.如果交换机在声明的时候,人为制定一些复杂参数 自动删除 持久化 间接等
        //使用构造器 链路调用生成
        return ExchangeBuilder
                .directExchange("direct-demo-ex")
                .durable(false).build();
    }
    //channel.queueDeclare(名字,持久化,专属,自动删除,其他)
    @Bean
    public Queue demoQ(){
        log.info("构造demo的队列");
        //1.方案 直接new
        //return new Queue("demo.queue",false,false,false,null);
        //2.builder构建链式调用 更易读
        /*QueueBuilder.nonDurable("demo_q").exclusive().autoDelete()
                .expires(10000)
                .ttl(100000)
                .overflow(QueueBuilder.Overflow.dropHead)
                .build();*/
        return QueueBuilder.nonDurable("demo-q").build();
    }
    //绑定队列和交换机
    //channel.queueBind(队列,交换机,路由key值,map)
    //channel.exchangeBind
    @Bean
    public Binding bindingDemo(){
        log.info("构造demo的绑定关系");
        //1.方案1 直接new
        //new Binding("demo-q", Binding.DestinationType.QUEUE,"direct-demo-ex","demo-rk",null);
        //2.方案2
        Map<String,Object> headers=new HashMap<>();
        headers.put("name","王翠花");
        headers.put("x-match","all");
        return BindingBuilder.bind(demoQ()).to(directDemoEx())
                .with("demo-rk").and(headers);
    }
}
